package com.huruwo.serialporthelper.utils;

import android.util.Log;


import static android.content.ContentValues.TAG;

/**
 * 读串口线程
 */
public abstract class SerialReadThread {


    /**
     * 收到数据的缓存
     */
    private byte[] buffer      = new byte[1024];
    /**
     * 标记收到数据的总大小
     */
    private int    currentSize = 0;


    public SerialReadThread() {
    }

    /**
     * 处理获取到的数据，解决粘包
     *
     * @param received
     * @param size
     */
    public void onDataReceive(final byte[] received, final int size) {

        // SYN RES PTROL ADDR SLEN COMMAND APPDATA CRC16
        // 2   3   1     2    2    2       *       2     字节
        // 0   2   5     6    8    10      12      12+*  偏移
        //3AA300000001000000000000000000140902000100000B000B00000000000000FFFFFFFFB72C
        //1A0400000000FFFFFFFF2B94
        final String s = ByteUtil.bytes2HexStr(received, 0, size);
       /* if (size==24&&s.startsWith("55AA1416")&&s.endsWith("FF")){
            processReceiveCardData(s.substring(10,18));
        }*/
        //        Log.e("--->", "收到：" + s);
        // 先缓存收到的数据,长度超过的时候,重置位置到0
        if (currentSize + size >= buffer.length) {
            currentSize = 0;
        }
        System.arraycopy(received, 0, buffer, currentSize, size);
        currentSize += size;
        int temp = 0; // 下标
        int frameStart = 0;// 开始位置下标
        int frameEnd = 0;

        while (temp < currentSize) {
            // 如果长度不满足最小长度，则跳出循环，等下新数据
            if (currentSize - temp >= Protocols.MIN_SIZE) {
                // 第1个字节不为 3A，则直接下一轮
                if (buffer[temp++] != Protocols.FRAME_HEAD_0) {
                    continue;
                }
                // 第2个字节不为 A3，则直接下一轮
                if (buffer[temp++] != Protocols.FRAME_HEAD_1) {
                    continue;
                }
                // 开始处理帧，先回溯2位，得到帧头位置

                frameStart = temp - 2;

                // 得到数据长度
                String slenStr = ByteUtil.bytes2HexStr(buffer, frameStart + 14, 2);
                int slen = (int) ByteUtil.hexStr2decimal(slenStr);

                // slen包括command和appdata，所以要把command的两字节减去
                int total = Protocols.MIN_SIZE + slen - 2;
                // 得到帧
                frameEnd = frameStart + total;

                // 缓存长度不小于帧末索引，否则此帧无效，继续查找
                if (currentSize < frameEnd) {
                    break;
                }

                // 找到crc16
                String crc16 = ByteUtil.bytes2HexStr(buffer, frameEnd - 2, 2);
                // 除开CRC16的数据
                byte[] other = new byte[total - 2];
                System.arraycopy(buffer, frameStart, other, 0, other.length);
                // 计算其他数据的crc16
                String otherCrc16 = CRC16Utils.getCRC16(other);
                //LogPlus.e("收到otherCrc16：" + otherCrc16);

                Log.e("1++", "收到otherCrc16：" + otherCrc16 + "\t" + crc16);

                Log.e("1++", "收到数据" + ByteUtil.bytes2HexStr(buffer));
                if (crc16.equals(otherCrc16)) {
                    Log.e("1+", "------> CRC验证成功 7559");
                    String command = ByteUtil.bytes2HexStr(buffer, frameStart + 16, 2);
                    String appdata = ByteUtil.bytes2HexStr(buffer, frameStart + 18, slen - 2);
                    // 所有数据
                    String allData = ByteUtil.bytes2HexStr(buffer, frameStart, total);

                    //LogPlus.e("收到命令：" + allData);
                    // 处理数据
                    //processReceiveData(command, appdata, allData);
                    Log.e(TAG, "onDataReceive: appdata-->" + appdata);
                    HeartbeatParam param = new HeartbeatParam(appdata);
                    Log.e("-->", "---->" + param.toString());
                    showText(" 重量:" + param.weight + "KG-- 阻抗:" + param.fst + "欧-- 身高是:" + param.height+"cm");


                    if (currentSize > frameEnd) {
                        // 未处理的数据
                        //将未处理的数据remain替换从0开始替换到buffer
                        System.arraycopy(buffer, frameEnd, buffer, 0, currentSize - frameEnd);
                        currentSize = currentSize - frameEnd;
                        temp = 0;
                    } else if (currentSize == frameEnd) {
                        currentSize = 0;
                        break;
                    }
                } else {
                    // 不一致则继续，找到下一个3AA3
                    Log.e("1+", "------> CRC验证失败 7559");

                    continue;
                }
            } else {
                break;
            }
        }
        // 如果下标跟缓存长度一样，则说明没有待处理数据，缓存清零
        if (temp == currentSize) {
            Log.e(TAG, "onDataReceive: 缓存清零");
            currentSize = 0;
        }
    }

    public abstract void showText(String text);

}
